package com.thekernel.youdaoyun.util;

import com.thekernel.youdaoyun.exception.MyException;
import com.thekernel.youdaoyun.exception.impl.DataAlreadyExistsException;
import com.thekernel.youdaoyun.exception.impl.DataNotFoundException;
import com.thekernel.youdaoyun.exception.impl.SystemErrorException;
import org.springframework.web.multipart.MultipartFile;

import java.io.*;
import java.nio.charset.StandardCharsets;
import java.util.Objects;

/**
 * @Author TheKernel
 * @Date 2019/10/02 6:10 下午
 * @Version 1.0
 * @Description 用于定义File工具类
 */
public class FileUtils {

    private static final String PATH = "data";
    private static final String AVATAR_PATH = "avatar";
    private static final String IMAGE_PATH = "image";
    private static final String SEPARATOR = File.separator;


    /**
     * 创建文件
     *
     * @param content 文件内容
     * @return 随机生成的文件名
     * @throws MyException 文件已存在、文件名错误等
     */
    public static String createFile(String content) throws MyException {
        String filename = PasswordUtils.encryptFilename();
        File file = new File(PATH + SEPARATOR + filename);
        // check if file exists
        if (file.exists()) {
            throw new DataAlreadyExistsException();
        }
        // create file dir
        if (!file.getParentFile().exists()) {
            if (!file.getParentFile().mkdirs()) {
                throw new SystemErrorException();
            }
        }
        try {
            if (file.createNewFile()) {
                // write content
                writeFile(file, content);
            } else {
                throw new SystemErrorException();
            }
        } catch (IOException e) {
            e.printStackTrace();
            throw new SystemErrorException();
        }
        return filename;
    }

    /**
     * 重命名文件
     *
     * @param newName 新笔记名
     * @param oldName 旧笔记名
     * @throws SystemErrorException 重命名失败
     */
    public static String renameFile(String newName, String oldName) throws MyException {
        String filename = PasswordUtils.encryptFilename();
        String newPath = PATH + SEPARATOR + filename;
        String oldPath = PATH + SEPARATOR + oldName;

        File oldFile = new File(oldPath);
        File newFile = new File(newPath);

        if (!oldFile.renameTo(newFile)) {
            throw new SystemErrorException();
        }
        return filename;
    }

    /**
     * 删除文件
     *
     * @param filePath 文件路径
     * @throws DataNotFoundException 删除笔记报错
     */
    public static void deleteFile(String filePath) throws DataNotFoundException {
        String filename = PATH + SEPARATOR + filePath;
        File file = new File(filename);

        if (!file.delete()) {
            throw new DataNotFoundException();
        }
    }

    /**
     * 读取文件
     *
     * @param filename 文件路径
     * @throws DataNotFoundException 文件不存在等
     */
    public static String readFile(String filename) throws DataNotFoundException {
        File file = new File(PATH + SEPARATOR + filename);
        StringBuilder returnString = new StringBuilder();

        try (BufferedReader reader = new BufferedReader(
                new InputStreamReader(
                        new FileInputStream(file),
                        StandardCharsets.UTF_8
                )
        )
        ) {
            String line;
            // 一次读入一行，直到读入null为文件结束
            while ((line = reader.readLine()) != null) {
                returnString.append(line).append("\n");
            }
        } catch (IOException e) {
            e.printStackTrace();
//            throw new DataNotFoundException();
            return "";
        }
        return returnString.toString();
    }

    /**
     * 更新文件
     *
     * @param filename 文件路径
     * @param content  文件内容
     * @throws SystemErrorException 更新失败
     */
    public static void updateFile(String filename, String content) throws MyException {
        File file = new File(PATH + SEPARATOR + filename);
        writeFile(file, content);
    }

    /**
     * 上传头像
     *
     * @param avatar 头像文件
     * @return 头像路径
     */
    public static String uploadAvatar(MultipartFile avatar) {
        String avatarName = PasswordUtils.encryptFilename();
        int index = Objects.requireNonNull(avatar.getOriginalFilename()).lastIndexOf(".");
        String dataPath = AVATAR_PATH + SEPARATOR + avatarName + avatar.getOriginalFilename().substring(index);
        try {
            BufferedOutputStream out = new BufferedOutputStream(
                    new FileOutputStream(
                            new File(Objects.requireNonNull(dataPath))
                    )
            );
            out.write(avatar.getBytes());
            out.flush();
            out.close();
        } catch (Exception e) {
            e.printStackTrace();
        }
        return avatarName;
    }

    /**
     * 上传图片
     *
     * @param image 图片文件
     * @return 图片名
     */
    public static String uploadImage(MultipartFile image) {
        int index = Objects.requireNonNull(image.getOriginalFilename()).lastIndexOf(".");
        String imageName = PasswordUtils.encryptFilename() + image.getOriginalFilename().substring(index);
        String dataPath = IMAGE_PATH + SEPARATOR + imageName;
        try {
            BufferedOutputStream out = new BufferedOutputStream(
                    new FileOutputStream(
                            new File(Objects.requireNonNull(dataPath))
                    )
            );
            out.write(image.getBytes());
            out.flush();
            out.close();
        } catch (Exception e) {
            e.printStackTrace();
        }
        return imageName;
    }

//    public static void deleteDir(File file) throws SystemErrorException {
//        if (file.isDirectory()) {
//            File[] files = file.listFiles();
//            for (File file2 : files) {
//                deleteDir(file2);
//            }
//            if(!file.delete())
//                throw new SystemErrorException();
//        } else {
//            if(!file.delete())
//                throw new SystemErrorException();
//        }
//    }

    private static void writeFile(File file, String noteContent) throws MyException {
        try {
            BufferedWriter out = new BufferedWriter(
                    new OutputStreamWriter(
                            new FileOutputStream(file),
                            StandardCharsets.UTF_8
                    )
            );
            out.write(noteContent);
            out.flush();
        } catch (IOException e) {
            throw new SystemErrorException();
        } catch (NullPointerException e) {
            throw new DataNotFoundException();
        }
    }

}
